package com.sc.byahi.user.shared;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.rpc.IsSerializable;

public abstract class AbstractEntity<T> implements HasProperty, IsSerializable {

	private static final long serialVersionUID = 1L;
	/**
	 * In GAE, there are basically two IDs, one, a long type of id which is a sequence, and another one a string like 'aglub19hcHBfaWRyDgsSCEVtcGxveWVlGBYM' which is made basically from appid, object
	 * type and object id. When we search entities, we get Entity object which contains everything as properties. To convert this object, we use Objectify 'Free' classes. To convert those to normal
	 * entities, we must have @Id annotation so that Objectify puts the long value in the id field. This field will be later used to derive the id from the object. so the dbkey stores the real id in
	 * string like 'aglub19hcHBfaWRyDgsSCEVtcGxveWVlGBYM'
	 */
	@Deprecated
	protected String dbKey = null;

	public Map<String, Object> getProperties() {
		Map<String, Object> properties = new HashMap<String, Object>();
		for (String prop : getPropertyNames()) {
			properties.put(prop, getProperty(prop));
		}
		return properties;
	}

	public void setProperties(Map<String, Object> properties) {
		for (Map.Entry<String, Object> entry : properties.entrySet()) {
			setProperty(entry.getKey(), entry.getValue());
		}
	}
	@Override
	public List<String> getPropertyNames() {
		List<String> props = new ArrayList<String>();
		props.addAll(getUnindexedPropertyNames());
		props.addAll(getIndexedPropertyNames());
		return props;
	}
	
	public abstract List<String> getUnindexedPropertyNames();
	public abstract List<String> getIndexedPropertyNames();
		
	@Override
	public int hashCode() {
		return getId().hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof AbstractEntity)) {
			return false;
		}
		return ((AbstractEntity) obj).getId().equals(this.getId());
	}

	abstract T getId();
}
